package com.zhiche.wms.service.opbaas.impl;

import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import com.google.common.collect.Maps;
import com.zhiche.wms.core.supports.BaseException;
import com.zhiche.wms.core.supports.enums.InterfaceEventEnum;
import com.zhiche.wms.core.supports.enums.TableStatusEnum;
import com.zhiche.wms.core.utils.SnowFlakeId;
import com.zhiche.wms.domain.mapper.opbaas.OpTaskMapper;
import com.zhiche.wms.domain.model.opbaas.OpDeliveryPoint;
import com.zhiche.wms.domain.model.opbaas.OpTask;
import com.zhiche.wms.domain.model.opbaas.StatusLog;
import com.zhiche.wms.domain.model.otm.OtmOrderRelease;
import com.zhiche.wms.domain.model.sys.User;
import com.zhiche.wms.dto.base.PageVo;
import com.zhiche.wms.dto.base.ResultDTOWithPagination;
import com.zhiche.wms.dto.opbaas.paramdto.TaskControllerParamDTO;
import com.zhiche.wms.dto.opbaas.resultdto.TaskDetailResultDTO;
import com.zhiche.wms.dto.opbaas.resultdto.TaskReleaseResultDTO;
import com.zhiche.wms.dto.opbaas.resultdto.TaskResultDTO;
import com.zhiche.wms.service.common.IntegrationService;
import com.zhiche.wms.service.constant.Task;
import com.zhiche.wms.service.dto.OTMEvent;
import com.zhiche.wms.service.opbaas.ExceptionToOTMService;
import com.zhiche.wms.service.opbaas.IDeliveryPointService;
import com.zhiche.wms.service.opbaas.IStatusLogService;
import com.zhiche.wms.service.opbaas.ITaskService;
import com.zhiche.wms.service.otm.IOtmOrderReleaseService;
import com.zhiche.wms.service.sys.IUserService;
import com.zhiche.wms.service.utils.BusinessNodeExport;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 作业任务 服务实现类
 * </p>
 *
 * @author user
 * @since 2018-05-24
 */
@Service
public class TaskServiceImpl extends ServiceImpl<OpTaskMapper, OpTask> implements ITaskService {

    @Autowired
    private IUserService userService;
    @Autowired
    private IOtmOrderReleaseService releaseService;
    @Autowired
    private BusinessNodeExport nodeExport;
    @Autowired
    private IntegrationService integrationService;
    @Autowired
    private IStatusLogService statusLogService;
    @Autowired
    private IDeliveryPointService deliveryPointService;
    @Autowired
    private SnowFlakeId snowFlakeId;
    @Autowired
    private ExceptionToOTMService exceptionToOTMService;

    /**
     * <p>
     * 查询对应的订单信息,支持订单号/车架号查询模糊匹配
     * </p>
     *
     * @param dto 参数封装
     */
    @Override

    public List<TaskResultDTO> queryTaskInfo(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        String queryParam = dto.getQueryParam();
        if (StringUtils.isBlank(queryParam)) {
            throw new BaseException("查询车架号或订单号不能为空!");
        }
        if (TableStatusEnum.STATUS_0.getCode().equals(dto.getTaskType())) {
            //查询指令信息
            return queryInfoQuick(dto);
        } else {
            //查询任务信息
            return queryTasks(dto, loginUser);
        }
    }

    private List<TaskResultDTO> queryInfoQuick(TaskControllerParamDTO dto) {
        String queryParam = dto.getQueryParam();
        EntityWrapper<OtmOrderRelease> reEW = new EntityWrapper<>();
        reEW.ne("status", TableStatusEnum.STATUS_50.getCode())
                .andNew()
                .like("vin", queryParam, SqlLike.DEFAULT)
                .or()
                .like("cus_order_no", queryParam)
                .or()
                .eq("qr_code", queryParam)
                .orderBy("gmt_create", false)
                .orderBy("id", false);
        if (StringUtils.isNotBlank(dto.getPointId())){
            OpDeliveryPoint opDeliveryPoint = deliveryPointService.selectById(dto.getPointId());
            reEW.andNew().eq("origin_location_gid",opDeliveryPoint.getCode());
        }
        Page<OtmOrderRelease> page = new Page<>();
        Page<OtmOrderRelease> releasePage = releaseService.selectPage(page, reEW);
        List<OtmOrderRelease> releases = releasePage.getRecords();
        if (CollectionUtils.isEmpty(releases)) {
            throw new BaseException("未查询到" + queryParam + "的运单信息");
        }
        ArrayList<TaskResultDTO> result = Lists.newArrayList();
        for (OtmOrderRelease re : releases) {
            TaskResultDTO taskResultDTO = buildTaskDetail(re);
            taskResultDTO.setTaskType(dto.getTaskType());
            result.add(taskResultDTO);
        }
        return result;
    }

    private TaskResultDTO buildTaskDetail(OtmOrderRelease re) {
        TaskResultDTO taskResultDTO = new TaskResultDTO();
        taskResultDTO.setReleaseId(String.valueOf(re.getId()));
        taskResultDTO.setVehicle(re.getStanVehicleType());
        taskResultDTO.setDispatchNo(re.getShipmentGid());
        taskResultDTO.setOrderReleaseGid(re.getReleaseGid());
        taskResultDTO.setOriginCode(re.getOriginLocationGid());
        taskResultDTO.setOriginName(re.getOriginLocationName());
        taskResultDTO.setDestCode(re.getDestLocationGid());
        taskResultDTO.setDestName(re.getDestLocationName());
        taskResultDTO.setVin(re.getVin());
        taskResultDTO.setOrderNo(re.getCusOrderNo());
        taskResultDTO.setWayBillNo(re.getReleaseGid());
        taskResultDTO.setQrCode(re.getQrCode());
        taskResultDTO.setStanVehicleType(re.getStanVehicleType());
        return taskResultDTO;
    }

    private List<TaskResultDTO> queryTasks(TaskControllerParamDTO dto,
                                           User loginUser) {
        dto.setUserCode(loginUser.getCode());
        String userCode = dto.getUserCode();
        HashMap<String, Object> params = Maps.newHashMap();
        String queryParam = dto.getQueryParam();
        params.put("queryParam", queryParam);
        params.put("userCode", userCode);
        params.put("userId", loginUser.getId());
        params.put("cancel", TableStatusEnum.STATUS_50.getCode());
        params.put("start", 0);
        params.put("end", 10);
        params.put("taskType", dto.getTaskType());
        params.put("likeVin", "%" + queryParam + "%");
        params.put("orderBy", "a.gmt_create desc,a.id desc,c.type asc");
        //首页查询用户对应起运地下的所有运单
        List<TaskResultDTO> dtoList = baseMapper.queryTaskInfo(params);
        if (CollectionUtils.isEmpty(dtoList)) {
            throw new BaseException("未查询到对应的运单信息!");
        }
        return dtoList;
    }

    /**
     * <p>
     * app首页--任务列表查询
     * </p>
     *
     * @param dto 参数封装
     */
    @Override
    public ResultDTOWithPagination<List<TaskResultDTO>> queryTaskList(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        dto.setUserCode(loginUser.getCode());
        String userCode = dto.getUserCode();
        String taskType = dto.getTaskType();
        int pageNo = dto.getPageNo();
        if (StringUtils.isBlank(taskType)) {
            throw new BaseException("任务类型不能为空!");
        }
        if (pageNo < 1) {
            throw new BaseException("页码不正确!");
        }
        //查用户发车点配置-->运单-->任务
        //HashMap<String, Object> params = Maps.newHashMap();
        //params.put("userCode", userCode);
        //params.put("status10", TableStatusEnum.STATUS_10.getCode());
        //params.put("start", dto.getStartIndex());
        //params.put("end", dto.getPageSize());
        //List<TaskReleaseResultDTO> data = opTaskMapper.selectReleaseInfo(params);
        //if (CollectionUtils.isEmpty(data)) {
        //    throw new BaseException("未查询到用户:" + userCode + "关联的运单信息");
        //}
        //生成对应的任务
        //SnowFlakeId flakeId = new SnowFlakeId(31L, 31L);
        //ArrayList<OpTask> taskBatch = Lists.newArrayList();
        //List<TaskResultDTO> resultData = Lists.newArrayList();
        //for (TaskReleaseResultDTO selectDTO : data) {
        //    //查询本地有无对应的任务生成
        //    if (TableStatusEnum.STATUS_YES.getCode().equals(selectDTO.getIsSeek())) {
        //        //寻车-查询本地有无对应的任务生成
        //        insertAndGetTask(userCode, flakeId, taskBatch, resultData, selectDTO, TableStatusEnum.STATUS_10.getCode());
        //    }
        //    if (TableStatusEnum.STATUS_YES.getCode().equals(selectDTO.getIsMove())) {
        //        //移车
        //        insertAndGetTask(userCode, flakeId, taskBatch, resultData, selectDTO, TableStatusEnum.STATUS_20.getCode());
        //    }
        //    if (TableStatusEnum.STATUS_YES.getCode().equals(selectDTO.getIsPick())) {
        //        //提车
        //        insertAndGetTask(userCode, flakeId, taskBatch, resultData, selectDTO, TableStatusEnum.STATUS_30.getCode());
        //    }
        //
        //}
        //if (CollectionUtils.isNotEmpty(taskBatch)) {
        //    opTaskMapper.insertTaskBatch(taskBatch);
        //}
        //根据类型分页返回
        HashMap<String, Object> queryParam = Maps.newHashMap();
        queryParam.put("status10", TableStatusEnum.STATUS_10.getCode());
        queryParam.put("status20", TableStatusEnum.STATUS_20.getCode());
        queryParam.put("status50", TableStatusEnum.STATUS_50.getCode());
        queryParam.put("userCode", userCode);
        queryParam.put("userId", loginUser.getId());
        queryParam.put("taskType", taskType);
        queryParam.put("start", dto.getStartIndex());
        queryParam.put("end", dto.getPageSize());
        queryParam.put("orderBy", "c.gmt_modified desc");
        queryParam.put("pointId", dto.getPointId());
        List<TaskResultDTO> taskResultDTOList = baseMapper.queryTaskList(queryParam);
        if (CollectionUtils.isEmpty(taskResultDTOList)) {
            throw new BaseException("未查询到用户:" + userCode + "此项任务信息");
        }
        int count = baseMapper.countTaskList(queryParam);
        ResultDTOWithPagination<List<TaskResultDTO>> pagination = new ResultDTOWithPagination<>();
        PageVo pageVo = new PageVo();
        pageVo.setPageNo(dto.getPageNo());
        pageVo.setTotalRecord(count);
        pageVo.setPageSize(dto.getPageSize());
        pagination.setPageVo(pageVo);
        pagination.setData(taskResultDTOList);
        return pagination;
    }


    /**
     * 使用page封装查询数据
     */
    @Override
    public Page<TaskResultDTO> queryTaskPage(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        String taskType = dto.getTaskType();
        if (StringUtils.isBlank(taskType)) {
            throw new BaseException("任务类型不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        //根据类型分页返回
        Page<TaskResultDTO> page = new Page<>();
        EntityWrapper<TaskResultDTO> ew = new EntityWrapper<>();
        ew.eq("type", taskType)
                .eq("user_id", loginUser.getId())
                .ne("status", TableStatusEnum.STATUS_50.getCode())
                .andNew()
                .eq("taskStatus", TableStatusEnum.STATUS_10.getCode())
                .or()
                .eq("taskStatus", TableStatusEnum.STATUS_20.getCode())
                .orderBy("gmt_create", false)
                .orderBy("taskId", false);
        page.setCurrent(dto.getPageNo());
        page.setSize(dto.getPageSize());
        List<TaskResultDTO> list = baseMapper.queryTaskPage(page, ew);
        page.setRecords(list);
        return page;
    }


    /**
     * <p>
     * 如果是通过快速附码进入,taskType -0 关联指令节点
     * 扫码获取任务详情,任务顺序展示
     * </p>
     *
     * @param dto 参数封装
     * @return 返回值
     */
    @Override
    public TaskDetailResultDTO getDetailByScan(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        String queryParam = dto.getQueryParam();
        if (StringUtils.isBlank(queryParam)) {
            throw new BaseException("查询车架号或订单号不能为空!");
        }
        if (TableStatusEnum.STATUS_0.getCode().equals(dto.getTaskType())) {
            TaskDetailResultDTO taskDetailResultDTO = queryQuickScan(dto);
            String send = exceptionToOTMService.isSend(taskDetailResultDTO.getVin(), taskDetailResultDTO.getOriginName());
            if (StringUtils.isNotBlank(send)){
                taskDetailResultDTO.setIsCanSend(send);
            }
            return taskDetailResultDTO;
        } else {
            TaskDetailResultDTO taskDetailResultDTO = queryTaskScan(dto, loginUser);
            String send = exceptionToOTMService.isSend(taskDetailResultDTO.getVin(), taskDetailResultDTO.getOriginName());
            if (StringUtils.isNotBlank(send)){
                taskDetailResultDTO.setIsCanSend(send);
            }
            return taskDetailResultDTO;
        }
    }

    private TaskDetailResultDTO queryQuickScan(TaskControllerParamDTO dto) {
        EntityWrapper<OtmOrderRelease> reEW = new EntityWrapper<>();
        String queryParam = dto.getQueryParam();
        reEW.ne("status", TableStatusEnum.STATUS_50.getCode())
                .andNew()
                .like("vin", queryParam, SqlLike.DEFAULT)
                .or()
                .eq("cus_order_no", queryParam)
                .or()
                .eq("qr_code", queryParam)
                .orderBy("gmt_create", false)
                .orderBy("id", false);
        if (StringUtils.isNotBlank(dto.getPointId())){
            OpDeliveryPoint opDeliveryPoint = deliveryPointService.selectById(dto.getPointId());
            reEW.eq("origin_location_gid",opDeliveryPoint.getCode());
        }
        List<OtmOrderRelease> releases = releaseService.selectList(reEW);
        if (CollectionUtils.isEmpty(releases)) {
            throw new BaseException("未查询到" + queryParam + "的运单信息");
        }
        OtmOrderRelease release = releases.get(0);
        TaskDetailResultDTO result = new TaskDetailResultDTO();
        result.setQrCode(release.getQrCode());
        result.setReleaseId(String.valueOf(release.getId()));
        result.setVehicle(release.getStanVehicleType());
        result.setDispatchNo(release.getShipmentGid());
        result.setOrderReleaseGid(release.getReleaseGid());
        result.setOriginCode(release.getOriginLocationGid());
        result.setOriginName(release.getOriginLocationName());
        result.setDestCode(release.getDestLocationGid());
        result.setDestName(release.getDestLocationName());
        result.setVin(release.getVin());
        result.setOrderNo(release.getCusOrderNo());
        result.setWayBillNo(release.getReleaseGid());
        result.setStanVehicleType(release.getStanVehicleType());
        result.setOtmStatus(release.getStatus());
        result.setTaskType(dto.getTaskType());
        return result;
    }

    private TaskDetailResultDTO queryTaskScan(TaskControllerParamDTO dto, User loginUser) {
        String queryParam = dto.getQueryParam();
        dto.setUserCode(loginUser.getCode());
        String userCode = dto.getUserCode();
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("queryParam", queryParam);
        params.put("likeVin", "%" + queryParam + "%");
        params.put("userCode", userCode);
        params.put("userId", loginUser.getId());
        params.put("status50", TableStatusEnum.STATUS_50.getCode());
        params.put("orderBy", "a.gmt_create desc,a.id desc");
        params.put("start", 0);
        params.put("end", 1);
        //首页查询用户对应起运地下的所有运单
        List<TaskReleaseResultDTO> dtoList = releaseService.queryRealeaseInfo(params);
        if (CollectionUtils.isEmpty(dtoList)) {
            throw new BaseException("未查询到对应的运单信息!");
        }
        TaskReleaseResultDTO resultDTO = dtoList.get(0);
        String locationGid = resultDTO.getSourceLocationGid();
        if (StringUtils.isBlank(locationGid)) {
            throw new BaseException("该车辆:" + resultDTO.getAttribute7() + "发车点编码为空!");
        }
        if (resultDTO.getId() == null) {
            throw new BaseException("该用户CODE:" + userCode + "未关联发车点:" + locationGid);
        }
        //查询任务详情,及关联的二维码
        HashMap<String, Object> map = Maps.newHashMap();
        map.put("releaseGid", resultDTO.getOrderReleaseGid());
        map.put("status50", TableStatusEnum.STATUS_50.getCode());
        map.put("userId", loginUser.getId());
        map.put("start", 0);
        map.put("end", 10);
        map.put("orderBy", "b.type,b.status");
        map.put("pointId", dto.getPointId());
        map.put("taskType", dto.getTaskType());
        List<TaskDetailResultDTO> result = baseMapper.getTaskDetailScan(map);
        if (CollectionUtils.isNotEmpty(result)) {
            for (TaskDetailResultDTO detailResultDTO : result) {
                if (TableStatusEnum.STATUS_10.getCode().equals(detailResultDTO.getTaskStatus())) {
                    return detailResultDTO;
                }
            }
            return result.get(result.size() - 1);
        }
        return null;
    }

    /**
     * <p>
     * 提车首页-根据任务获取任务明细信息
     * </p>
     *
     * @param dto 参数封装
     */
    @Override
    public TaskDetailResultDTO getTaskDetail(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        if (TableStatusEnum.STATUS_0.getCode().equals(dto.getTaskType())) {
            TaskDetailResultDTO detailQuick = getDetailQuick(dto);
            String send = exceptionToOTMService.isSend(detailQuick.getVin(), detailQuick.getOriginName());
            if (StringUtils.isNotBlank(send)){
                detailQuick.setIsCanSend(send);
            }
            return detailQuick;
        } else {
            TaskDetailResultDTO detailNorma = getDetailNormal(dto, loginUser);
            String send = exceptionToOTMService.isSend(detailNorma.getVin(), detailNorma.getOriginName());
            if (StringUtils.isNotBlank(send)){
                detailNorma.setIsCanSend(send);
            }
            return detailNorma;
        }
    }

    private TaskDetailResultDTO getDetailQuick(TaskControllerParamDTO dto) {
        String releaseId = dto.getId();
        if (StringUtils.isBlank(releaseId)) {
            throw new BaseException("运单明细ID不能为空");
        }
        OtmOrderRelease orderRelease = releaseService.selectById(releaseId);
        if (orderRelease == null) {
            throw new BaseException("未查询到运单id" + releaseId + "的运单信息");
        }
        TaskDetailResultDTO result = new TaskDetailResultDTO();
        result.setTaskNode(TableStatusEnum.STATUS_0.getCode());
        result.setTaskCreate(new Date());
        result.setTaskStart(new Date());
        result.setBindTime(new Date());
        result.setQrCode(orderRelease.getQrCode());
        result.setReleaseId(String.valueOf(orderRelease.getId()));
        result.setVehicle(orderRelease.getStanVehicleType());
        result.setDispatchNo(orderRelease.getShipmentGid());
        result.setOrderReleaseGid(orderRelease.getReleaseGid());
        result.setOriginCode(orderRelease.getOriginLocationGid());
        result.setOriginName(orderRelease.getOriginLocationName());
        result.setDestCode(orderRelease.getDestLocationGid());
        result.setDestName(orderRelease.getDestLocationName());
        result.setVin(orderRelease.getVin());
        result.setOrderNo(orderRelease.getCusOrderNo());
        result.setWayBillNo(orderRelease.getReleaseGid());
        result.setTaskType(TableStatusEnum.STATUS_0.getCode());
        result.setStanVehicleType(orderRelease.getStanVehicleType());
        result.setOtmStatus(orderRelease.getStatus());
        return result;
    }

    private TaskDetailResultDTO getDetailNormal(TaskControllerParamDTO dto, User loginUser) {
        dto.setUserCode(loginUser.getCode());
        String taskId = dto.getId();
        if (StringUtils.isBlank(taskId)) {
            throw new BaseException("任务id不能为空!");
        }
        HashMap<String, Object> queryParam = Maps.newHashMap();
        queryParam.put("taskId", taskId);
        queryParam.put("status50", TableStatusEnum.STATUS_50.getCode());
        queryParam.put("start", 0);
        queryParam.put("end", 1);
        List<TaskDetailResultDTO> result = baseMapper.getTaskDetail(queryParam);
        if (CollectionUtils.isEmpty(result)) {
            throw new BaseException("未查询到任务id" + taskId + "的任务信息");
        }
        return result.get(0);
    }

    /**
     * <p>
     * 提车任务开始任务,绑定司机
     * </p>
     *
     * @param dto 参数封装
     */
    @Override
    public void updatePickTask(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        dto.setDriverCode(loginUser.getCode());
        dto.setDriverName(loginUser.getName());
        dto.setDriverPhone(loginUser.getMobile());
        String taskId = dto.getTaskId();
        String taskType = dto.getTaskType();

        if (StringUtils.isBlank(taskId)) {
            throw new BaseException("任务id不能为空!");
        }
        if (StringUtils.isBlank(taskType)) {
            throw new BaseException("任务类型不能为空!");
        }
        OpTask task = baseMapper.selectById(taskId);
        if (!TableStatusEnum.STATUS_30.getCode().equals(task.getType())) {
            throw new BaseException("任务id:" + taskId + "任务类型不匹配!");
        }
        if (task.getStatus().equals(TableStatusEnum.STATUS_20.getCode()) ||
                task.getStatus().equals(TableStatusEnum.STATUS_30.getCode())) {
            throw new BaseException("任务状态为:" + task.getStatus() + "不支持此操作!");
        }
        updateTaskPick(dto, task);
        // 获取运单信息
        OtmOrderRelease release = setReleaseAndStatusLog(loginUser, taskId, task);
        // 回传OTM
        new Thread(() -> {
            OTMEvent event = integrationService.getOtmEvent(
                    taskId,
                    release.getReleaseGid(),
                    InterfaceEventEnum.OR_FIND.getCode(),
                    release.getShipmentGid(), "开始提车回传OTM");
            String res = nodeExport.exportEventToOTM(event);
            if (StringUtils.isNotBlank(res)) {
                //记录日志
                integrationService.insertExportLog(taskId,
                        event,
                        res,
                        "开始提车回传OTM",
                        InterfaceEventEnum.OR_FIND.getCode());
            }
        }).start();
    }

    private OtmOrderRelease setReleaseAndStatusLog(User loginUser, String taskId, OpTask task) {
        EntityWrapper<OtmOrderRelease> ew = new EntityWrapper<>();
        ew.eq("release_gid", task.getWaybillNo())
                .ne("status", TableStatusEnum.STATUS_50.getCode());
//                .eq("status", TableStatusEnum.STATUS_10.getCode());
        List<OtmOrderRelease> releaseList = releaseService.selectList(ew);
        if (CollectionUtils.isEmpty(releaseList)) {
            throw new BaseException("未查询到taskId:" + taskId + "的运单信息");
        }
        if (releaseList.size() > 1) {
            throw new BaseException("查询到taskId:" + taskId + "多条运单信息");
        }
        OtmOrderRelease release = releaseList.get(0);
        OtmOrderRelease orderRelease = new OtmOrderRelease();
        orderRelease.setId(release.getId());
        orderRelease.setStatus(TableStatusEnum.STATUS_WMS_PICKUP.getCode());
        releaseService.updateById(orderRelease);
        StatusLog statusLog = new StatusLog();
        statusLog.setTableType(TableStatusEnum.STATUS_10.getCode());
        statusLog.setTableId(String.valueOf(release.getId()));
        statusLog.setStatus(TableStatusEnum.STATUS_WMS_PICKUP.getCode());
        statusLog.setStatusName(TableStatusEnum.STATUS_WMS_PICKUP.getDetail());
        statusLog.setUserCreate(loginUser.getName());
        statusLogService.insert(statusLog);
        return release;
    }

    private void updateTaskPick(TaskControllerParamDTO dto, OpTask task) {
        task.setId(dto.getTaskId());
        task.setDriverCode(dto.getDriverCode());
        task.setDriverName(dto.getDriverName());
        task.setDriverPhone(dto.getDriverPhone());
        task.setStatus(TableStatusEnum.STATUS_20.getCode());
        task.setStartTime(new Date());
        task.setGmtModified(null);
        task.setUserModified(dto.getDriverCode());
        baseMapper.updateById(task);
        //
        OpTask oldTask = baseMapper.selectById(dto.getTaskId());
        EntityWrapper<OpTask> ew = new EntityWrapper<>();
        ArrayList<String> types = Lists.newArrayList();
        types.add(TableStatusEnum.STATUS_20.getCode());
        types.add(TableStatusEnum.STATUS_10.getCode());
        ew.in("type", types)
                .in("status", types)
                .eq("dispatch_no", oldTask.getDispatchNo())
                .eq("waybill_no", oldTask.getWaybillNo());
        OpTask needFinish = new OpTask();
        needFinish.setStatus(TableStatusEnum.STATUS_30.getCode());
        needFinish.setUserModified("auto");
        baseMapper.update(needFinish, ew);

    }


    /**
     * <p>
     * 移车任务-完成移车
     * </p>
     *
     * @param dto 参数封装
     */
    @Override
    public void updateMoveTask(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        dto.setDriverCode(loginUser.getCode());
        dto.setDriverPhone(loginUser.getMobile());
        dto.setDriverName(loginUser.getName());
        String taskId = dto.getTaskId();
        String taskType = dto.getTaskType();
        if (StringUtils.isBlank(taskId)) {
            throw new BaseException("任务id不能为空!");
        }
        if (StringUtils.isBlank(taskType)) {
            throw new BaseException("任务类别不能为空!");
        }
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("taskId", taskId);
        params.put("taskType", taskType);
        params.put("status50", TableStatusEnum.STATUS_50.getCode());
        List<TaskDetailResultDTO> detailResultDTOList = baseMapper.getTaskDetail(params);
        if (CollectionUtils.isEmpty(detailResultDTOList)) {
            throw new BaseException("未查询到taskId:" + taskId + "的移车任务,请确认!");
        }
        if (detailResultDTOList.size() > 1) {
            throw new BaseException("查询到taskId:" + taskId + "的多条移车任务!");
        }
        TaskDetailResultDTO detailDTO = detailResultDTOList.get(0);
        if (TableStatusEnum.STATUS_30.getCode().equals(detailDTO.getTaskStatus())) {
            throw new BaseException("查询到taskId:" + taskId + "任务已经完成,无需重复操作!");
        }
        updateTaskMove(dto);
        //回写运单状态
        setReleaseAndStatusLog(loginUser, detailDTO);

        new Thread(() -> {
            OTMEvent event = integrationService.getOtmEvent(
                    taskId,
                    detailDTO.getOrderReleaseGid(),
                    InterfaceEventEnum.OR_FIND.getCode(),
                    detailDTO.getDispatchNo(), "移车完成回传OTM");
            String res = nodeExport.exportEventToOTM(event);
            if (StringUtils.isNotBlank(res)) {
                //记录日志
                integrationService.insertExportLog(taskId, event, res, "移车完成回传OTM",
                        InterfaceEventEnum.OR_FIND.getCode());
            }
        }).start();
    }

    private void updateTaskMove(TaskControllerParamDTO dto) {
        OpTask task = new OpTask();
        task.setStatus(TableStatusEnum.STATUS_30.getCode());
        task.setStartTime(new Date());
        task.setFinishTime(new Date());
        task.setUserModified(dto.getDriverCode());
        task.setDriverCode(dto.getDriverCode());
        task.setDriverName(dto.getDriverName());
        task.setDriverPhone(dto.getDriverPhone());
        task.setGmtModified(new Date());
        task.setId(dto.getTaskId());
        baseMapper.updateById(task);
    }

    private void setReleaseAndStatusLog(User loginUser, TaskDetailResultDTO detailDTO) {
        OtmOrderRelease release = new OtmOrderRelease();
        release.setStatus(TableStatusEnum.STATUS_WMS_MOVE.getCode());
        release.setId(Long.valueOf(detailDTO.getReleaseId()));
        releaseService.updateById(release);
        StatusLog statusLog = new StatusLog();
        statusLog.setTableType(TableStatusEnum.STATUS_10.getCode());
        statusLog.setTableId(detailDTO.getReleaseId());
        statusLog.setStatus(TableStatusEnum.STATUS_WMS_MOVE.getCode());
        statusLog.setStatusName(TableStatusEnum.STATUS_WMS_MOVE.getDetail());
        statusLog.setUserCreate(loginUser.getName());
        statusLogService.insert(statusLog);
    }


    /**
     * <p>
     * 个人任务
     * </p>
     */
    @Override
    public ResultDTOWithPagination<List<TaskResultDTO>> getMyTaskByType(TaskControllerParamDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空!");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new BaseException("用户编码不能为空!");
        }
        dto.setDriverCode(loginUser.getCode());
        String driverCode = dto.getDriverCode();
        String taskType = dto.getTaskType();
        int pageNo = dto.getPageNo();
        if (pageNo < 1) {
            throw new BaseException("页码不正确!");
        }
        if (StringUtils.isBlank(driverCode)) {
            throw new BaseException("司机编码不能为空!");
        }
        if (StringUtils.isBlank(taskType)) {
            throw new BaseException("查询任务类型不能为空!");
        }
        HashMap<String, Object> params = Maps.newHashMap();
        params.put("startOrFinish", taskType);
        params.put("driverCode", driverCode);
        params.put("userId",loginUser.getId());
        params.put("status50", TableStatusEnum.STATUS_50.getCode());
        params.put("orderBy", "c.gmt_create desc,c.type asc,c.id desc");
        params.put("start", dto.getStartIndex());
        params.put("end", dto.getPageSize());
        params.put("pointId", dto.getPointId());
        List<TaskResultDTO> list = baseMapper.selectTaskStartOrFinishByParam(params);
        int count = baseMapper.countTaskStartOrFinishByParam(params);
        ResultDTOWithPagination<List<TaskResultDTO>> result = new ResultDTOWithPagination<>();
        PageVo pageVo = new PageVo();
        pageVo.setPageNo(pageNo);
        pageVo.setPageSize(dto.getPageSize());
        pageVo.setTotalRecord(count);
        result.setPageVo(pageVo);
        result.setData(list);
        return result;
    }

    @Override
    public Page<TaskResultDTO> queryTaskList(Page<TaskResultDTO> page) {
        Map<String, Object> condition = page.getCondition();
        Wrapper<TaskResultDTO> ew = new EntityWrapper<>();
        if (condition != null) {
            if (condition.containsKey("taskType") && Objects.nonNull(condition.get("taskType"))) {
                ew.eq("type", condition.get("taskType"));
            }
            if (condition.containsKey("taskStatus") && Objects.nonNull(condition.get("taskStatus"))) {
                ew.eq("taskStatus", condition.get("taskStatus"));
            }
            if (condition.containsKey("vin") && Objects.nonNull(condition.get("vin"))) {
                String[] split = condition.get("vin").toString().split(",");
                List<String> vins = Arrays.asList(split);
                ew.in("vin", vins).orNew().like("vin", condition.get("vin").toString());
            }
            if (condition.containsKey("orderNo") && Objects.nonNull(condition.get("orderNo"))) {
                ew.like("cus_order_no", condition.get("orderNo").toString());
            }
            if (condition.containsKey("startAddr") && Objects.nonNull(condition.get("startAddr"))) {
                ew.like("origin_location_gid", condition.get("startAddr").toString());
            }
            if (condition.containsKey("startDate") && Objects.nonNull(condition.get("startDate"))) {
                ew.ge("start_time", condition.get("startDate").toString());
            }
            if (condition.containsKey("endDate") && Objects.nonNull(condition.get("endDate"))) {
                ew.le("start_time", condition.get("endDate").toString());
            }
            if (condition.containsKey("pointId") && Objects.nonNull(condition.get("pointId"))) {
                OpDeliveryPoint opDeliveryPoint = deliveryPointService.selectById(condition.containsKey("pointId"));
                ew.eq("origin_location_gid", opDeliveryPoint.getCode());
            }
        }
        ew.ne("otmStatus", TableStatusEnum.STATUS_50.getCode());
        ew.orderBy("waybill_no", false);
        ew.orderBy("type");
        ew.orderBy("gmt_create");
        List<TaskResultDTO> dtoList = baseMapper.selectTaskInfoByPage(page, ew);
        page.setRecords(dtoList);
        return page;
    }

    private void insertAndGetTask(String userCode,
                                  SnowFlakeId flakeId,
                                  ArrayList<OpTask> taskBatch,
                                  List<TaskResultDTO> resultData,
                                  TaskReleaseResultDTO selectDTO,
                                  String code) {
        //查询本地
        HashMap<String, Object> selectMap = Maps.newHashMap();
        selectMap.put("dispatch_no", selectDTO.getAttribute16());
        selectMap.put("waybill_no", selectDTO.getOrderReleaseGid());
        selectMap.put("type", code);
        List<OpTask> tasks = baseMapper.selectByMap(selectMap);
        if (CollectionUtils.isEmpty(tasks)) {
            //未查询到对应的类型任务
            OpTask task = getOpTask(userCode, selectDTO, flakeId, code);
            taskBatch.add(task);
            getResultData(userCode, resultData, selectDTO, task);
        } else {
            if (tasks.size() > 1) {
                throw new BaseException("运单:" + selectDTO.getOrderReleaseGid() +
                        ",指令:" + selectDTO.getAttribute16() + "存在多条移车任务");
            }
            getResultData(userCode, resultData, selectDTO, tasks.get(0));
        }
    }


    private void getResultData(String userCode,
                               List<TaskResultDTO> resultData,
                               TaskReleaseResultDTO resultDTO,
                               OpTask task) {
        TaskResultDTO resultTask = new TaskResultDTO();
        resultTask.setTaskId(task.getId());
        resultTask.setOriginCode(resultDTO.getSourceLocationGid());
        resultTask.setOriginName(resultDTO.getSourceLocationName());
        resultTask.setDestCode(resultDTO.getDestLocationGid());
        resultTask.setDestName(resultDTO.getDestLocationName());
        resultTask.setTaskStatus(task.getStatus());
        resultTask.setTaskType(task.getType());
        resultTask.setOrderNo(resultDTO.getAttribute1());
        resultTask.setWayBillNo(resultDTO.getOrderReleaseGid());
        resultTask.setVin(resultDTO.getAttribute7());
        resultTask.setUserCode(userCode);
        resultData.add(resultTask);
    }


    private OpTask getOpTask(String userCode,
                             TaskReleaseResultDTO resultDTO,
                             SnowFlakeId flakeId,
                             String statusCode) {
        OpTask task = new OpTask();
        task.setId(String.valueOf(flakeId.nextId()));
        task.setDispatchNo(resultDTO.getAttribute16()); //指令号取release运输指令号
        task.setWaybillNo(resultDTO.getOrderReleaseGid());//运单号取release系统单号
        task.setType(statusCode);
        task.setGmtCreate(new Date());
        task.setStatus(TableStatusEnum.STATUS_10.getCode());
        task.setGmtModified(new Date());
        task.setUserCreate(userCode);
        return task;
    }


}
